<?php

namespace common\utils;

use App\Services\SettingService;

class RSACrypt
{
    /**
     * @return array
     */
    public static function needFilterKeywords()
    {
        return ['email', 'mobile', 'qq', 'wechat', 'skype', 'idcard', 'card'];
    }

    /**
     * openssl 双向加密
     *
     * @return Encrypt|null
     */
    public static function xmcrypt()
    {
        static $mt = null;
        if (is_null($mt)) {
            $key = SettingService::getItem(SettingService::APP_KEY);
            $mt = new Encrypt($key);
        }
        return $mt;
    }


    /**
     * 解密
     *
     * @param string $data
     * @return null|string
     */
    public static function rsaDecrypt(string $data = null)
    {
        if (!strlen($data)) {
            return $data;
        }
        try{
            $mt = RSACrypt::xmcrypt()->decrypt($data);
        }catch (\Throwable $e){
            return $data;
        }
        return $mt ? $mt : $data;
    }


    /**
     * 加密
     *
     * @param string $data
     * @return string
     */
    public static function rsaEncrypt(string $data = null)
    {
        if (!strlen($data)) {
            return $data;
        }
        try{
            $mt = RSACrypt::xmcrypt()->encrypt($data);
        }catch (\Throwable $e){
            return $data;
        }
        return  $mt ? $mt : $data;
    }

    /**
     * 个人信息加、解密
     *
     * @param array $data 多维数组
     * @param int   $handler Enc 加密 Dec 解密
     * @return array
     */
    public static function rsaPatch(array &$data = null, int $handler = Encrypt::DECRYPT)
    {
        if (!$data) {
            return $data;
        }
        try{
            foreach ($data as $key => &$datum) {
                if (is_array($datum)) {
                    $datum = RSACrypt::rsaPatch($datum, $handler);
                } else {
                    if (in_array($key, RSACrypt::needFilterKeywords(), true)) {
                        $datum = $handler == Encrypt::DECRYPT ? RSACrypt::rsaDecrypt($datum) : RSACrypt::rsaEncrypt($datum);
                    }
                }
            }
        }catch (\Throwable $e){
            return $data;
        }
        return $data;
    }

}
